/**
 * 加载模板
 * 模板分为多个sheet页
 * @param {axios} http 
 * @param {string} tpmlId 模板id
 * @param {object} params 页面参数
 * @return 返回sheet参数以及根据模板填充完毕的参数信息，供创建sheet实例 
 */
function loadSheetConfig(http, tpmlId, params, cells) {
    //加载模板

    //加载数据源
    // let dsm = loadSheetDs(sheetTpml.dsConfig, params)
    let dsm = loadSheetDs()
    //填充数据

    console.log("插入前", JSON.parse(JSON.stringify(cells)))
    let datas = fillSheetData(cells, dsm)
    console.log("插入后", datas)


    return datas//临时
}
/**
 * 加载数据源
 * @param {object} dsConfig
 * @return 返回数据源集合 
 * 
 * 参数: params = {time:${time},name:${name}}
 * 
 */
function loadSheetDs(dsConfigs, params) {
    //解析输入参数
    // for (var i = 0; i < dsConfigs.length; i++) {
    //     for (var key in dsConfigs[i].param) {
    //         var ns = parseVariable(dsConfigs[i].param[key])
    //         if (ns) {
    //             dsConfigs[i].param[key] = params[ns.ds]
    //         }
    //     }
    // }
    // console.log("aaaaaaa", dsConfigs)
    var res = {
        name: "ds1",
        label: "数据源1",
        columns: [{ name: "id", label: "主键标识" }, { name: "name", label: "测试名称" }, { name: "time", label: "时间" }],
        records: [
            ["1", "测试1", new Date()],
            ["2", "测试2", new Date()],
            ["3", "测试3", new Date()],
            ["4", "测试4", new Date()],
        ]
    }
    let ds = newDs(res)
    //加载数据源
    return {
        dss: [ds],
        get: function (name) {
            for (let i = 0; i < this.dss.length; i++) {
                if (name == this.dss[i].name || name == this.dss[i].label) {
                    return this.dss[i]
                }
            }
            return {}
        }
    }
}
/**
 * 根据后台返回结果生成数据源实例
 * @param {object} res 
 * @returns 返回实例化的数据源
 */
function newDs(res) {
    let ds = {
        name: res.name,
        label: res.label,
        columns: res.columns,//后台返回的表格列名称
        records: res.records,//后台返回的记录
        //读取一个单元格
        get: function (r, c) {
            return this.records[r][c]
        },
        //读取一行
        getRows: function (r) {
            return records[r]
        },
        //读取一列
        getCols: function (c) {
            if (typeof c === "string") {
                c = this.getColId(c)
            }
            if (c < 0 || (this.records.length == 0)) {
                return []
            }
            let values = []
            for (let r = 0; r < this.records.length; r++) {
                values.push(this.records[r][c])
            }
            return values
        },
        //根据名称读取列索引
        getColId: function (name) {
            let c = null
            for (let i = 0; i < this.columns.length; i++) {
                if (name.toLowerCase() === this.columns[i].name.toLowerCase() || name.toLowerCase() === this.columns[i].label.toLowerCase()) {
                    c = i
                    break
                }
            }
            return c
        },
        //读取列标签
        getColLabels: function () {
            let labels = []
            for (let i = 0; i < this.columns.length; i++) {
                labels.push(this.columns[i].label)
            }
            return labels
        }
    }
    return ds
}
/**
 * 数据填充变量规则
 * U = 向上  D = 向下  L = 向左   R = 向右
 *    A                   B                    C                          ...
 * ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
 * 1                      ${ds.lable}                                     $代表数据源的单个数据，例：${ds.data[0][3]}
 * 2  ...                 ...                                             ...
 * 3  ${ds.columns(0)}   ${ds.columns(1)}    ${ds.columns(2)}             单个填充:设置单个单元格
 * 4  $r{ds.columns}                                                      自动填充:单元格根据columns一维数据向右填充，其中的label
 * 5  $d{ds.columnName}                                                   自动填充:单元格根据columnName(列名，不区分)一维数据向下填充
 * 6  $r{ds.cols(0)}                                                      自动填充:单元格根据cols一维数据向下填充
 * 6  $r{ds.getRows(0)}                                                   自动填充:单元格根据rows一维数据向下填充
 * 7  ${ds.datas}                                                         自动填充:单元格根据datas二维数据向右，向下填充
 * 8  ...
 * 
 * 注：
 *  a.填充时，增加的单元格保留设置单元格的格式
 *  b.新增时，参数单元格的被增加单元格的格式向填充方向移动，同时保留单元格的格式及数据
 */
/**
 * 填充模板数据
 * @param {object} cells 
 * @param {array} dsm
 * @return 返回填充完毕的sheet数据
 * 
 * ${ds}  意味着在此单元格处，向右扩充列，向下扩充行
 * ${ds.data(1,2)} 在此处填充第1行，第2列的数据
 * $d{ds.row(1)} 在此处向下填充数据源第1行的数据
 * $d{ds.col(n)} 在此处向下填充数据源第n列或列名为n的列的数据
 * $d{ds.colName} 在此处向下填充
 * 
 */
function fillSheetData(cells, dsm) {
    //所有的需要填充的变量
    var vars = []
    for (var r = 0; r < cells.length; r++) {
        for (var c = 0; c < cells[r].length; c++) {
            if (cells[r][c]) {
                cells[r][c].r = r
                cells[r][c].c = c
            }
            if (cells[r][c] && isDsVariable(cells[r][c].v)) {
                cells[r][c].vs = cells[r][c].v
                vars.push(cells[r][c])
            }
        }
    }
    //逐个变量进行解析其数据
    for (var i = 0; i < vars.length; i++) {
        var cell = vars[i]//设置的数据源
        var va = parseVariable(cell.v)//解析设置信息
        var ds = dsm.get(va.ds)//得到设置的数据源
        if (!ds) { return }
        var datas = []
        if (va.d == undefined || va.d == "") {//无方向
            if (va.k == "_name" || va.k == "_label" || va.k == "_名称" || va.k == "_标题") {
                var cell = { ...cell }
                cell.v = ds[va.k.replace(/_/g, "")]
                datas.push([cell])
            } else if (va.k == undefined || va.k == "" || va.k != "data" || va.k == "集合") {//将数据源的二维数据转换为cell数据
                //${ds} ${ds.data} ${ds.集合}
                for (let j = 0; j < ds.records.length; j++) {
                    let row = []
                    for (let k = 0; k < ds.records[j].length; k++) {
                        data = { ...cell }
                        data.v = ds.records[j][k]
                        row.push(data)
                    }
                    datas.push(row)
                }
            } else if ((va.k == "name" || va.k == "label" || va.k == "名称" || va.k == "标题") && va.r == undefined && va.c == undefined) {//得到数据源的点数据
                // ${ds.name} ${ds.label} ${ds.标题} ${ds.名称}
                let data = { ...cell }
                if (va.k == "名称") {
                    data.v = this.name
                } else if (va.k == "标题") {
                    data.v = this.label
                } else {
                    data.v = this[va.k]
                }
                datas.push(data)
            }
        } else {//有方向
            if (va.k != undefined) {//以列名取列的数据
                //$(r){ds.age} $下{ds.年龄}
                let values = ds.getCols(va.k)
                if (va.d.toLowerCase() == "d" || va.d == "下") {
                    if (va.k == "columns") {
                        for (let i = 0; i < ds.columns.length; i++) {
                            let data = { ...cell }
                            data.v = ds.columns[i].label
                            datas.push([data])
                        }
                    } else {
                        for (let j = 0; j < values.length; j++) {
                            let data = { ...cell }
                            data.v = values[j]
                            datas.push([data])
                        }
                    }
                } else if (va.d.toLowerCase() == "r" || va.d == "右") {
                    var rows = []
                    if (va.k == "columns") {
                        for (let i = 0; i < ds.columns.length; i++) {
                            let data = { ...cell }
                            data.v = ds.columns[i].label
                            rows.push(data)
                        }
                    } else {
                        for (let j = 0; j < values.length; j++) {
                            let data = { ...cell }
                            data.v = values[j]
                            rows.push(data)
                        }
                    }
                    datas.push(rows)
                }
            }
        }
        //插入单元格
        insertCells(cells, va.o, datas)
    }
    return cells
}


function insertCells(cells, o, iss) {
    let colLen = cells[0].length//列数量
    let rowLen = cells.length//行数量
    let irowLen = iss.length//插入行的数量
    let icolLen = iss[0].length//插入的列数量
    let z = iss[0][0]//原点
    if (o == "$" && icolLen > 1) {    //向右移动右侧区域
        let rss = []
        for (let i = z.r; i < z.r + irowLen; i++) {
            if (cells[i]) {
                let ls = cells[i].slice(z.c + 1, colLen)//取一行
                rss.push(ls)
            }
        }
        //原位置置空
        for (let i = z.r; i < z.r + irowLen; i++) {
            for (let j = z.c + 1; j < colLen; j++) {
                setCell(cells, i, j, null)
            }
        }
        //右移动单元格
        for (let i = 0; i < rss.length; i++) {
            for (let j = 0; j < rss[i].length; j++) {
                setCell(cells, z.r + i, z.c + icolLen + j, rss[i][j])
            }
        }
    }
    if (o == "$" && irowLen > 1) {
        //向下移动下方区域
        let dss = []
        for (let i = z.r + 1; i < rowLen; i++) {
            let ds = cells[i].slice(z.c, z.c + icolLen)
            dss.push(ds)
        }
        //原单元格位置置空
        for (let i = z.r + 1; i < z.r + irowLen; i++) {
            for (let j = z.c; j < z.c + icolLen; j++) {
                setCell(cells, i, j, null)
            }
        }
        //下移动单元格
        let r = z.r + irowLen
        for (let i = 0; i < dss.length; i++) {
            let c = z.c
            for (let j = 0; j < dss[0].length; j++) {
                setCell(cells, r, c, dss[i][j])
                c += 1
            }
            r += 1
        }
    }
    //设置插入单元格
    for (let i = 0; i < irowLen; i++) {
        for (let j = 0; j < iss[i].length; j++) {
            //设置插入单元格
            setCell(cells, z.r + i, z.c + j, iss[i][j])
        }
    }
}
function setCell(cells, r, c, cell) {
    if (!cell && (c >= cells[0].length || r >= cells.length)) {
        return
    }
    let rlen = cells.length
    let clen = cells[0].length
    if (r > rlen - 1) {//如果行不存在，增加行
        let rs = r - rlen + 1
        for (let i = 0; i < rs; i++) {
            cells.push(new Array(clen).fill(null))
        }
        rlen = cells.length
    }
    if (c > clen - 1) {//如果列不存在，则增加列
        let cs = c - clen + 1
        if (cs > 0) {
            for (let i = 0; i < rlen; i++) {
                cells[i].push(new Array(cs).fill(null))
            }
        }
    }
    cells[r][c] = cell
}

//判断是否是数据源变量
function isDsVariable(str) {
    if (typeof str != "string") { return false }
    const regex = /\s*[\$\@][^}]+\}/g;
    return regex.test(str.replaceAll(/\s/g, ""))
}
function parseVariables(str) {
    if (typeof str != "string") { return [] }
    const regex = /\$[^}]+\}/g;
    const regex1 = /^\s*\r*\n*\t*([\$\@])\s*([a-zA-Z]*)\s*\{\s*([a-zA-Z\u4e00-\u9fa50-9]+)\s*\.*\s*([a-zA-Z\u4e00-\u9fa50-9]+)\s*\(*\s*([0-9]*)\s*,*\s*([0-9]*)\s*\)*}/
    const matchs = str.match(regex)
    let variables = []
    for (let i = 0; i < matchs.length; i++) {
        variables.push(parseVariable(matchs[i]))
    }
    return variables
}
//解析变量中的相关参数
function parseVariable(str) {
    if (typeof str != "string") { return [] }
    // const regex = /^\s*\r*\n*\t*\$\s*([a-zA-Z]*)\s*\{\s*([a-zA-Z\u4e00-\u9fa5\d]+)\s*\.*\s*([a-zA-Z\u4e00-\u9fa5\d]+)\s*\(*\s*([\d]*)\s*,*\s*([\d]*)\s*\)*}/
    const regex = /([\$\@])([\w]*)\{([\w\d]+)\.*([\w]*)\}/;
    const s = str.replaceAll(/\s/g, "")
    const match = s.match(regex);
    if (match) {
        return { in: match.input, o: match[1], d: match[2], ds: match[3], k: match[4] }
    }
    return {}
}
/**
 * 更新某个sheet的数据
 * @param {object} luckysheet 
 * @param {number} index
 * @param {[[]...]} cells 
 */
function updateSheet(luckysheet, index, sheet) {
    luckysheet.updateSheet({ data: [sheet] })
}
function createSheet(luckysheet, container, sheet) {
    luckysheet.create({ container: container, data: [sheet] })
}
// function updateSheet(luckysheet, index, cells) {
//     const sheets = luckysheet.getAllSheets()
//     for (var i = 0; i < sheets.length; i++) {
//         if (i == index) {
//             sheets[i].data = cells
//             luckysheet.updateSheet({ data: [sheets[i]] })
//             break
//         }
//     }
// }
function updateSheetCells(luckysheet, index, cells) {
    const sheets = luckysheet.getAllSheets()
    for (var i = 0; i < sheets.length; i++) {
        if (i == index) {
            sheets[i].celldata = cells
            sheets[i].data = []
            luckysheet.updateSheet({ data: [sheets[i]] })
            break
        }
    }
}
function getSheetTmpl(luckysheet) {
    var sheets = luckysheet.getAllSheets()
    var data = []
    for (var i = 0; i < sheets.length; i++) {
        var tmp = {
            celldata: sheets[i].celldata,
            config: sheets[i].config,
            row: sheets[i].row,
            column: sheets[i].column,
            showGridLines: 0, //是否显示网格线
        }
        data.push(tmp)
    }
    return { data: data }
}
// 默认单元格的参数
// {
//     "ct": { //单元格值格式
//         "fa": "General",  //格式名称为自动格式
//         "t": "n" //格式类型为数字类型
//     },
//     "v": 233, //内容的原始值为 233
//     "m": 233, //内容的显示值为 233
//     "bg": "#f6b26b", //背景为 "#f6b26b"
//     "ff": 1, // 字体为 "Arial"
//     "fc": "#990000", //字体颜色为 "#990000"
//     "bl": 1, //字体加粗
//     "it": 1, //字体斜体
//     "fs": 9, //字体大小为 9px
//     "cl": 1, //启用删除线
//     "ht": 0, //水平居中
//     "vt": 0, //垂直居中
//     "tr": 2, //文字旋转 -45°
//     "tb": 2, //文本自动换行
//     "ps": { //批注
//         "left": 92, //批注框左边距
//         "top": 10, //批注框上边距
//         "width": 91, //批注框宽度
//         "height": 48, //批注框高度
//         "value": "I am a comment", //批注内容
//         "isshow": true //批注框为显示状态
//     },
//     "f": "=SUM(233)" //单元格是一个求和公式
//     "ro": 1         // 只读
// }





// var sheetTmpl = {
//     container: "luckysheet", //容器的ID
//     loading: {}, //自定义loading
//     column: 60, //空表格默认的列数量
//     row: 84, //空表格默认的行数据量
//     allowCopy: true, //是否允许拷贝
//     showtoolbar: true, //是否第二列显示工具栏
//     showinfobar: true, //是否显示顶部名称栏
//     showsheetbar: true, //是否显示底部表格名称区域
//     showstatisticBar: true, //是否显示底部计数栏
//     pointEdit: false, //是否是编辑器插入表格模式
//     pointEditUpdate: null, //编辑器表格更新函数
//     pointEditZoom: 1, //编辑器表格编辑时缩放比例
//     data: [
//         { "name": "Sheet1", color: "", "status": "1", "order": "0", "data": [], "config": {}, "index": 0 },
//         { "name": "Sheet2", color: "", "status": "0", "order": "1", "data": [], "config": {}, "index": 1 },
//         { "name": "Sheet3", color: "", "status": "0", "order": "2", "data": [], "config": {}, "index": 2 }
//     ],//每个sheet页的数据
//     title: "测试软件", //表格的名称
//     userInfo: false,// 右上角的用户信息展示样式，支持 1. boolean类型：false:不展示，true:展示默认 '<i style="font-size:16px;color:#ff6a00;" class="fa fa-taxi" aria-hidden="true"></i> rabbit' ，2. HTML模板字符串或者普通字符串，如：'<i style="font-size:16px;color:#ff6a00;" class="fa fa-taxi" aria-hidden="true"></i> Lucky'或者'用户名'， 3. 对象格式，设置 userImage：用户头像地址 和 userName：用户名 4. 不设置或者设置undefined同设置false
//     userMenuItem: [
//         { url: "www.baidu.com", "icon": '<i class="fa fa-folder" aria-hidden="true"></i>', "name": "我的表格" },
//         { url: "www.baidu.com", "icon": '<i class="fa fa-sign-out" aria-hidden="true"></i>', "name": "退出登陆" }
//     ], //点击右上角的用户信息弹出的菜单
//     myFolderUrl: "www.baidu.com", //左上角<返回按钮的链接
//     config: {}, //表格行高、列宽、合并单元格、公式等设置
//     fullscreenmode: true, //是否全屏模式，非全屏模式下，标记框不会强制选中。
//     devicePixelRatio: window.devicePixelRatio, //设备比例，比例越大表格分标率越高
//     allowEdit: true, //是否允许前台编辑
//     loadUrl: "", // 配置loadUrl的地址，luckysheet会通过ajax请求表格数据，默认载入status为1的sheet数据中的所有data，其余的sheet载入除data字段外的所有字段
//     loadSheetUrl: "", //配置loadSheetUrl的地址，参数为gridKey（表格主键） 和 index（sheet主键合集，格式为[1,2,3]），返回的数据为sheet的data字段数据集合
//     gridKey: "", // 表格唯一标识符
//     updateUrl: "", //表格数据的更新地址
//     updateImageUrl: "", //缩略图的更新地址
//     allowUpdate: false, //是否允许编辑后的后台更新
//     functionButton: "", //右上角功能按钮，例如'<button id="" class="btn btn-primary" style="padding:3px 6px;font-size: 12px;margin-right: 10px;">下载</button>    <button id="" class="btn btn-primary btn-danger" style="    padding:3px 6px;    font-size: 12px;    margin-right: 10px;">分享</button>    <button id="luckysheet-share-btn-title" class="btn btn-primary btn-danger" style="    padding:3px 6px;    font-size: 12px;    margin-right: 10px;">秀数据</button>'
//     showConfigWindowResize: true, //图表和数据透视表的配置会在右侧弹出，设置弹出后表格是否会自动缩进
//     enableAddRow: true,//允许添加行
//     enableAddBackTop: false,//允许回到顶部
//     enablePage: false,//允许加载下一页
//     autoFormatw: false,  //自动格式化超过4位数的数字为 亿万格式 例：true or "true" or "TRUE"
//     accuracy: undefined,  //设置传输来的数值的精确位数，小数点后n位 传参数为数字或数字字符串，例： "0" 或 0
//     pageInfo: { 'queryExps': '', 'reportId': '', 'fields': '', 'mobile': '', 'frezon': '', 'currentPage': '', "totalPage": 10, "pageUrl": "", },
//     editMode: false, //是否为编辑模式
//     beforeCreateDom: null,//表格创建之前的方法
//     fireMousedown: null, //单元格数据下钻
//     lang: 'zh', //language
//     plugins: [{ name: 'chart' }], //plugins, e.g. ['chart']
//     forceCalculation: false,//强制刷新公式，公式较多会有性能问题，慎用
//     rowHeaderWidth: 46,
//     columnHeaderHeight: 20,
//     defaultColWidth: 73,
//     defaultRowHeight: 19,
//     defaultFontSize: 10,
//     limitSheetNameLength: true,    //是否限制工作表名的长度
//     defaultSheetNameMaxLength: 31,  //默认工作表名称的最大长度
//     sheetFormulaBar: true, //是否显示公式栏
//     showtoolbarConfig: {}, //自定义工具栏
//     showsheetbarConfig: {}, //自定义底部sheet页
//     showstatisticBarConfig: {}, //自定义计数栏
//     cellRightClickConfig: {}, //自定义单元格右键菜单
//     sheetRightClickConfig: {}, //自定义底部sheet页右击菜单
//     imageUpdateMethodConfig: {}, //自定义图片同步方式
// }

// //默认的数据源的参数
// var ds = {
//     name: "",//数据源名称
//     url: "",//请求的api
//     params: [{}],//访问后台api对应的参数,{db:"",tableName:"",where:"",whereArgs:[]}
// }
// var dss = {
//     "ds1": {
//         name: "",
//         label: "",
//         columns: [{ name: "", label: "" }],//后台返回的表格列名称
//         records: [[]],//后台返回的记录

//         //读取一个单元格
//         get: function (r, c) {
//             return this.records[r][c]
//         },
//         //读取一行
//         getRows: function (r) {
//             return records[r]
//         },
//         //读取一列
//         getCols: function (c) {
//             let values = []
//             for (let r = 0; r < this.records.length; r++) {
//                 values.push(this.records[r][c])
//             }
//         },
//         //根据名称读取列索引
//         getColId: function (name) {
//             let c = null
//             for (let i = 0; i < this.columns.length; i++) {
//                 if (name.toLowerCase() === column.name.toLowerCase() || name.toLowerCase() === column.label.toLowerCase()) {
//                     c = i
//                     break
//                 }
//             }
//             return c
//         },
//         //读取列标签
//         getColLabels: function () {
//             let labels = []
//             for (let i = 0; i < this.columns.length; i++) {
//                 labels.push(this.columns[i].label)
//             }
//             return labels
//         }
//     },
//     //加载所有数据源
//     load: function (http) {

//     },
//     //读取一个数据源
//     ds: function (dsName) {

//     }
// }
